package com.dpkit.manager.registry;

import com.dpkit.adapter.OrmAdapter;
import com.dpkit.annotation.OrmRegistry;
import com.dpkit.base.DpKitCondition;
import com.dpkit.base.exception.DpKitException;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import static com.dpkit.manager.factory.DpkitFactory.ORM_MAP;

@Component
public class OrmScannerBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        OrmRegistry ormRegistry =
                AnnotationUtils.findAnnotation(AopUtils.getTargetClass(bean), OrmRegistry.class);
        if(ormRegistry == null) {
            return bean;
        }
        if(!ClassUtils.isAssignableValue(OrmAdapter.class,bean)) {
            throw new DpKitException(bean.getClass() + "  doesn't implement OrmAdapter interface");
        }
        String orm = ormRegistry.value();
        DpKitCondition.checkArgument(StringUtils.hasLength(orm),"ORM cannot be empty！");
        Class<? extends OrmAdapter> ormClass = ORM_MAP.putIfAbsent(orm, (Class<OrmAdapter>) bean.getClass());
        DpKitCondition.checkArgument(ormClass == null, "The registered ORM name is duplicated");
        return bean;
    }
}
